import time
from typing import Union
from kernels.utils import RequestUtil
from plugins.censor.engine.baidu import BaiduCensor
from plugins.censor.engine.aliyun import AliyunCensor
from common.models.sys import SysCensorModel
from common.utils.urls import UrlUtil
from common.utils.config import ConfigUtil


class CensorDriver:
    REVIEW_QUESTION = "review_question"
    REVIEW_DRAWS = "review_draws"
    REVIEW_VIDEO = "review_video"
    REVIEW_MUSIC = "review_music"
    REVIEW_USERS = "review_users"
    REVIEW_TEXTS = "review_texts"
    REVIEW_IMAGE = "review_image"

    @classmethod
    async def text(cls, text: str, scene: str = None, user_id=0) -> Union[str, None]:
        """
        审查文本

        Args:
            text (str): 要审查的文本
            scene (str): 审查的场景 (review_question...)
            user_id (int): 来源用户

        Returns:
            str | None: str=不通过原因, None=通过

        Author:
            zero
        """
        if not text:
            return None

        if scene is not None:
            status = await ConfigUtil.get(type_="content_censor", key=scene) or 0
            if not int(status):
                return None

        channel = await ConfigUtil.get("content_censor", "channel")
        if channel == "aliyun":
            service = "comment_detection_pro"
            if scene == "review_users":
                service = "nickname_detection_pro"
            results = await AliyunCensor.text(text=text, service=service)
        else:
            results = await BaiduCensor.text(text=text)

        if results is not None:
            await cls.save_log(
                user_id=user_id,
                channel=channel,
                input_type="text",
                input_content=text,
                result=results
            )
        return results

    @classmethod
    async def image(cls, path: str, scene: str = None, user_id: int = 0) -> Union[str, None]:
        """
        审查图片

        Args:
            path (str): 要审查的图片地址 (https://www.baidu.com/aa.png)
            scene (str): 审查的场景 (review_image...)
            user_id (int): 来源用户

        Returns:
            str | None: str=不通过原因, None=通过

        Author:
            zero
        """
        if not path:
            return None

        if scene is not None:
            status = await ConfigUtil.get(type_="content_censor", key=scene) or 0
            if not int(status):
                return None

        channel = await ConfigUtil.get("content_censor", "channel")
        if channel == "aliyun":
            results = await AliyunCensor.image(path=path)
        else:
            results = await BaiduCensor.image(path=path)

        if results is not None:
            url = UrlUtil.to_relative_url(path)
            await cls.save_log(
                user_id=user_id,
                channel=channel,
                input_type="image",
                input_content=url,
                result=results
            )
        return results

    @classmethod
    async def save_log(cls, user_id: int, channel: str, input_type: str, input_content: str, result: str):
        """
        保存审查日志 (只记录不通过的)

        Args:
            user_id (int): 来源用户
            channel (str): 审查渠道
            input_type (str): 输入类型 (text, image)
            input_content (str): 输入内容
            result (str): 审核结果

        Author:
            zero
        """
        await SysCensorModel.create(
            user_id=user_id,
            channel=channel,
            input_type=input_type,
            input_content=input_content,
            censor_result=result,
            ip=RequestUtil.host,
            create_time=int(time.time())
        )
